package com.flyme.module.auth.provider.service.impl;

import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.flyme.common.core.http.OpenRestTemplate;
import com.flyme.module.auth.client.config.SocialOAuth2ClientDetails;
import com.flyme.module.auth.client.config.SocialOAuth2ClientProperties;
import com.flyme.module.auth.client.constants.AuthConstants;
import com.flyme.module.auth.client.service.ThirdPartyAuthService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.net.URLEncoder;
import java.util.Map;

/**
 * 微信oauth2认证实现类
 *
 * @author liuyadu
 */
@Service("wechatAuthService")
@Slf4j
public class WechatAuthServiceImpl implements ThirdPartyAuthService {
    @Autowired
    private OpenRestTemplate restTemplate;
    @Autowired
    private SocialOAuth2ClientProperties socialAuthProperties;
    /**
     * 微信 登陆页面的URL
     */
    private final static String AUTHORIZATION_URL = "%s?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=%s#wechat_redirect";
    /**
     * 获取token的URL
     */
    private final static String ACCESS_TOKEN_URL = "%s?appid=%s&secret=%s&code=%s&grant_type=authorization_code";

    /**
     * 获取用户信息的 URL，oauth_consumer_key 为 apiKey
     */
    private static final String USER_INFO_URL = "%s?access_token=%s&openid=%s&lang=zh_CN";


    private static final String OPEN_ID_URL = "https://api.weixin.qq.com/sns/jscode2session?";


    @Override
    public String getAuthorizationUrl() {
        String redirect_url= URLEncoder.encode(getClientDetails().getRedirectUri());
        String url = String.format(AUTHORIZATION_URL, getClientDetails().getUserAuthorizationUri(), getClientDetails().getClientId(), redirect_url, getClientDetails().getScope(),System.currentTimeMillis());
        return url;
    }

    @Override
    public  Map<String, String> getAccessToken(String code) {
        String url = String.format(ACCESS_TOKEN_URL, getClientDetails().getAccessTokenUri(), getClientDetails().getClientId(), getClientDetails().getClientSecret(), code);
        UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url);
        URI uri = builder.build().encode().toUri();
        String resp = restTemplate.getForObject(uri, String.class);
        System.out.println("微信getAccessToken："+resp);
        if (resp != null && resp.contains("access_token")) {
            Map<String, String> map = JSONUtil.toBean(resp,Map.class);
            return map;
        }
        log.error("QQ获得access_token失败，code无效，resp:{}", resp);
        return null;
    }



    @Override
    public String getOpenId(String accessToken) {
        String uIdParams = "access_token=" + accessToken;
        String resp = HttpUtil.post(OPEN_ID_URL, uIdParams);
        if (resp != null && resp.contains("openid")) {
            JSONObject jsonObject = ConvertToJson(resp);
            return jsonObject.getString("openid");
        }
        log.error("微信获得openid失败，accessToken无效，resp:{}", resp);
        return null;
    }

    @Override
    public JSONObject getUserInfo(String accessToken, String openId) {
        String url = String.format(USER_INFO_URL, getClientDetails().getUserInfoUri(), accessToken,  openId);
        String resp = restTemplate.getForObject(url, String.class);
        JSONObject data = JSONObject.parseObject(resp);
        return data;
    }
    /**
     * QQ接口返回类型是text/plain，此处将其转为json
     *
     * @param string
     * @return
     */
    private JSONObject ConvertToJson(String string) {
        string = string.substring(string.indexOf("(") + 1, string.length());
        string = string.substring(0, string.indexOf(")"));
        JSONObject jsonObject = JSONObject.parseObject(string);
        return jsonObject;
    }

    @Override
    public String refreshToken(String code) {
        return null;
    }

    /**
     * 获取登录成功地址
     *
     * @return
     */
    @Override
    public String getLoginSuccessUrl() {
        return getClientDetails().getLoginSuccessUri();
    }

    /**
     * 获取客户端配置信息
     *
     * @return
     */
    @Override
    public SocialOAuth2ClientDetails getClientDetails() {
        return socialAuthProperties.getOauth2().get(AuthConstants.LOGIN_WECHAT);
    }

}
